const db=require('../db/index.js')
const bcrypt = require('bcryptjs')
const jwt = require('jsonwebtoken')
const config = require('../config')
const queryDb = (sql, params) => {
  return new Promise((resolve, reject) => {
    db.query(sql, params, (err, result) => {
      if (err) reject(err);
      else resolve(result);
    });
  });
};

//获得小组
const getUserGroups = async (req, res) => {
  try {
    // 参数校验
    const { userId } = req.query;
    if (!userId || isNaN(Number(userId))) {
      return res.status(400).json({
        status: 400,
        message: "参数错误：用户ID不能为空且必须为数字"
      });
    }
    const targetUserId = Number(userId);

    // 查询用户加入的所有小组
    const queryGroupsSql = `
      SELECT 
        group_id AS groupId,
        group_name AS groupName,
        group_leader_id AS groupLeaderId,
        group_leader_nickname AS groupLeaderNickname,
        join_time AS joinTime,
        -- 角色判断：组长（creator）/普通成员（member）
        CASE 
          WHEN ? = group_leader_id THEN 'creator' 
          ELSE 'member' 
        END AS role
      FROM user_group_relation
      WHERE user_id = ?
      ORDER BY join_time DESC  -- 按加入时间倒序
      LIMIT 100  -- 限制最多100个小组
    `;
    // 关键修改：用 queryDb 替代 db.promise().query，直接接收 result
    const groupsResult = await queryDb(queryGroupsSql, [targetUserId, targetUserId]);

    // 处理无数据场景
    if (groupsResult.length === 0) {
      return res.status(200).json({
        status: 200,
        message: "暂无加入的小组，快去创建或加入小组吧",
        data: []
      });
    }

    // 补充查询每个小组的成员数量
    const groupIds = groupsResult.map(group => group.groupId);
    const queryMemberCountSql = `
      SELECT 
        group_id AS groupId,
        COUNT(DISTINCT user_id) AS memberCount
      FROM user_group_relation
      WHERE group_id IN (?)
      GROUP BY group_id
    `;
    const memberCountResult = await queryDb(queryMemberCountSql, [groupIds]);

    // 构建小组-成员数量映射表
    const memberCountMap = new Map(
      memberCountResult.map(item => [item.groupId, item.memberCount])
    );

    // 组装最终返回数据
    const groupList = groupsResult.map(group => ({
      groupId: group.groupId,
      groupName: group.groupName || "未命名小组",
      groupLeaderId: group.groupLeaderId,
      groupLeaderNickname: group.groupLeaderNickname || "未知用户",
      role: group.role,  // 'creator' 或 'member'
      joinTime: group.joinTime,
      memberCount: memberCountMap.get(group.groupId) || 1  // 至少包含当前用户
    }));

    // 返回成功响应
    return res.status(200).json({
      status: 200,
      message: "用户小组信息获取成功",
      data: groupList
    });

  } catch (err) {
    // 错误处理
    console.error("获取用户小组信息异常:", err.stack);
    res.status(500).json({
      status: 500,
      message: "获取小组信息失败：服务器内部错误",
      error: process.env.NODE_ENV === 'development' ? err.message : undefined
    });
  }
};
//获得小组聊天记录
const getGroupPosts = async (req, res) => {
  try {
    //参数校验
    const { groupId, page = 1, pageSize = 10 } = req.query;
    if (!groupId || isNaN(Number(groupId))) {
      return res.status(400).json({
        status: 400,
        message: "参数错误：小组ID（groupId）不能为空且必须为有效数字"
      });
    }
    const targetGroupId = Number(groupId);
    const currentPage = Math.max(Number(page), 1);
    const pageSizeNum = Math.max(Number(pageSize), 10);
    const offset = (currentPage - 1) * pageSizeNum;

    //校验小组是否存在
    const checkGroupSql = `
      SELECT id, name AS groupName 
      FROM study_groups 
      WHERE id = ?
    `;
    const groupResult = await queryDb(checkGroupSql, [targetGroupId]);
    if (groupResult.length === 0) {
      return res.status(404).json({
        status: 404,
        message: "该小组不存在或已解散"
      });
    }
    const groupName = groupResult[0].groupName;

    // 查询小组动态记录
    const queryPostsSql = `
      SELECT 
        gp.id AS postId,
        gp.user_id AS publisherId,
        u.nickname AS publisherNickname,
        u.avatar AS publisherAvatar,
        gp.content AS postContent,
        gp.image_url AS postImageUrl,
        gp.created_at AS publishTime,
        CASE WHEN gp.image_url IS NOT NULL THEN 1 ELSE 0 END AS hasImage
      FROM group_posts gp
      LEFT JOIN users u ON gp.user_id = u.id
      LEFT JOIN user_group_relation ugr ON gp.user_id = ugr.user_id AND gp.group_id = ugr.group_id
      WHERE gp.group_id = ?
        AND ugr.user_id IS NOT NULL
        AND gp.is_withdrawn = 0
      ORDER BY gp.created_at DESC
      LIMIT ?, ?
    `;
    const postsResult = await queryDb(queryPostsSql, [
      targetGroupId,
      offset,
      pageSizeNum
    ]);

    // 查询动态总数
    const queryTotalSql = `
      SELECT COUNT(*) AS total 
      FROM group_posts gp
      LEFT JOIN user_group_relation ugr ON gp.user_id = ugr.user_id AND gp.group_id = ugr.group_id
      WHERE gp.group_id = ? AND ugr.user_id IS NOT NULL
    `;
    const totalResult = await queryDb(queryTotalSql, [targetGroupId]);
    const totalPosts = totalResult[0].total;
    const totalPages = Math.ceil(totalPosts / pageSizeNum);
    // 处理无动态场景
    if (postsResult.length === 0) {
      return res.status(200).json({
        status: 200,
        message: `小组【${groupName}】暂无互动动态，快去发布第一条动态吧`,
        data: {
          groupId: targetGroupId,
          groupName,
          posts: [],
          pagination: {
            currentPage,
            pageSize: pageSizeNum,
            totalPosts,
            totalPages
          }
        }
      });
    }

    // 组装最终返回数据
    const formattedPosts = postsResult.map(post => ({
      postId: post.postId,
      publisherId: post.publisherId,
      publisherNickname: post.publisherNickname || "匿名用户",
      publisherAvatar: post.publisherAvatar || "/default-avatar.png",
      postContent: post.postContent || "",
      postImageUrl: post.postImageUrl,
      hasImage: post.hasImage === 1,
      publishTime: post.publishTime
    }));

    // 返回成功响应
    return res.status(200).json({
      status: 200,
      message: `成功获取小组【${groupName}】的互动动态`,
      data: {
        groupId: targetGroupId,
        groupName,
        posts: formattedPosts,
        pagination: {
          currentPage,
          pageSize: pageSizeNum,
          totalPosts,
          totalPages
        }
      }
    });

  } catch (err) {
    // 错误处理
    console.error("获取小组动态异常:", err.stack);
    res.status(500).json({
      status: 500,
      message: "获取小组动态失败：服务器内部错误",
      error: process.env.NODE_ENV === 'development' ? err.message : undefined
    });
  }
};
//发送消息
const sendGroupPost = async (req, res) => {
  try {
    const { groupId, userId, content = "", imageUrl = "" } = req.body;

    if (!groupId || isNaN(Number(groupId))) {
      return res.status(400).json({
        status: 400,
        message: "参数错误：小组ID（groupId）不能为空且必须为有效数字"
      });
    }
    if (!userId || isNaN(Number(userId))) {
      return res.status(401).json({
        status: 401,
        message: "未登录：用户ID（userId）不能为空且必须为有效数字"
      });
    }
    const targetGroupId = Number(groupId);
    const targetUserId = Number(userId);

    if (!content.trim() && !imageUrl.trim()) {
      return res.status(400).json({
        status: 400,
        message: "发送失败：请输入文字内容或上传图片（两者至少选一个）"
      });
    }

    if (imageUrl.trim() && !/^https?:\/\/.*/.test(imageUrl.trim())) {
      return res.status(400).json({
        status: 400,
        message: "图片URL格式错误：请输入有效的HTTP/HTTPS链接"
      });
    }

    const checkMemberSql = `
      SELECT user_id 
      FROM user_group_relation 
      WHERE user_id = ? AND group_id = ?
    `;
    const memberResult = await queryDb(checkMemberSql, [targetUserId, targetGroupId]);
    if (memberResult.length === 0) {
      return res.status(403).json({
        status: 403,
        message: "无权限：你不是该小组的成员，无法发送动态"
      });
    }

    const checkGroupSql = `
      SELECT id 
      FROM study_groups 
      WHERE id = ?
    `;
    const groupResult = await queryDb(checkGroupSql, [targetGroupId]);
    if (groupResult.length === 0) {
      return res.status(404).json({
        status: 404,
        message: "发送失败：该小组不存在或已解散"
      });
    }

    const insertPostSql = `
      INSERT INTO group_posts 
      (group_id, user_id, content, image_url)
      VALUES (?, ?, ?, ?)
    `;
    const insertResult = await queryDb(insertPostSql, [
      targetGroupId,
      targetUserId,
      content.trim(),
      imageUrl.trim()
    ]);

    const newPost = {
      postId: insertResult.insertId,
      groupId: targetGroupId,
      userId: targetUserId,
      content: content.trim(),
      imageUrl: imageUrl.trim(),
      publishTime: new Date().toISOString()
    };

    res.status(201).json({
      status: 200,
      message: "小组动态发送成功",
      data: newPost
    });

  } catch (err) {
    console.error("发送小组动态异常:", err.stack);
    res.status(500).json({
      status: 500,
      message: "发送小组动态失败：服务器内部错误",
      error: process.env.NODE_ENV === 'development' ? err.message : undefined
    });
  }
};
//撤回聊天记录
const groupChatWithdraw = async (req, res) => {
  try {
    // 解析请求参数
    const { id } = req.body;

    // 严格参数校验
    if (!id  || isNaN(Number(id ))) {
      return res.status(400).json({
        status: 400,
        message: "参数错误：消息ID（messageId）不能为空且必须为有效数字"
      });
    }
    const targetMessageId = Number(id);

    //校验：消息是否存在
    const checkMessageSql = `
      SELECT id, group_id,user_id, created_at
      FROM group_posts 
      WHERE id = ? 
        AND is_withdrawn = 0
    `;
    const messageResult = await queryDb(checkMessageSql, [targetMessageId]);

    //消息不存在/不属于当前用户/已撤回
    if (messageResult.length === 0) {
      return res.status(404).json({
        status: 404,
        message: "无法撤回：消息不存在、已撤回或你无权限撤回该消息"
      });
    }

    //撤回时间限制（如发送后2分钟内可撤回，按需开启）
    const messageCreateTime = new Date(messageResult[0].created_at);
    const now = new Date();
    const withdrawLimit = 2 * 60 * 1000; // 2分钟（毫秒）
    if (now - messageCreateTime > withdrawLimit) {
      return res.status(400).json({
        status: 400,
        message: "消息发送超过2分钟，无法撤回"
      });
    }

    //执行撤回操作（逻辑删除：更新is_withdrawn为1，保留消息记录）
    const withdrawSql = `
      UPDATE group_posts
      SET is_withdrawn = 1 
      WHERE id = ?
    `;
    const updateResult = await queryDb(withdrawSql, [targetMessageId]);

    // 验证撤回结果（理论上不会走到，因前面已校验消息存在）
    if (updateResult.affectedRows === 0) {
      return res.status(500).json({
        status: 500,
        message: "撤回失败：更新消息状态出错"
      });
    }

    // 返回成功响应
    res.status(200).json({
      status: 200,
      message: "消息撤回成功",
      data: {
        messageId: targetMessageId,
        withdrawTime: new Date().toISOString(),
        isWithdrawn: true
      }
    });

  } catch (err) {
    // 错误处理
    console.error("撤回消息异常:", err.stack);
    res.status(500).json({
      status: 500,
      message: "撤回消息失败：服务器内部错误",
      error: process.env.NODE_ENV === 'development' ? err.message : undefined
    });
  }
};
//创建小组
const createStudyGroup = async (req, res) => {
  try {
    // 解析请求参数
    const { 
      groupName,        
      description = ""  
    } = req.body;
    const userId = req.body.userId;

    // 严格参数校验
    if (!userId || isNaN(Number(userId))) {
      return res.status(401).json({
        status: 401,
        message: "未登录：请先登录后创建小组"
      });
    }
    const leaderId = Number(userId);

    if (!groupName || groupName.trim() === "") {
      return res.status(400).json({
        status: 400,
        message: "参数错误：小组名称不能为空"
      });
    }
    const trimmedGroupName = groupName.trim();
    if (trimmedGroupName.length > 50) {
      return res.status(400).json({
        status: 400,
        message: "参数错误：小组名称不能超过50个字符"
      });
    }

    // 检查小组名称重复
    const checkDuplicateSql = `
      SELECT id FROM study_groups WHERE name = ?
    `;
    const duplicateResult = await queryDb(checkDuplicateSql, [trimmedGroupName]);
    if (duplicateResult.length > 0) {
      return res.status(409).json({
        status: 409,
        message: `创建失败：“${trimmedGroupName}”已存在`
      });
    }

    // 查询创建者昵称
    const getLeaderNicknameSql = `
      SELECT nickname FROM users WHERE id = ?
    `;
    const leaderResult = await queryDb(getLeaderNicknameSql, [leaderId]);
    const groupLeaderNickname = leaderResult.length > 0 ? leaderResult[0].nickname : "未知用户";

    const insertGroupSql = `
      INSERT INTO study_groups 
      (name, leader_id, goal, created_at) 
      VALUES (?, ?, ?, CURRENT_TIMESTAMP)
    `;
    const groupResult = await queryDb(insertGroupSql, [
      trimmedGroupName,
      leaderId,
      description.trim()
    ]);
    const newGroupId = groupResult.insertId; // 新小组ID

    const insertMemberSql = `
      INSERT INTO group_members 
      (user_id, group_id, joined_at)
      VALUES (?, ?, CURRENT_TIMESTAMP)
    `;
    await queryDb(insertMemberSql, [leaderId, newGroupId]);

    // 组装返回数据，统计当前小组成员数
    const countMemberSql = `
      SELECT COUNT(*) AS memberCount FROM group_members WHERE group_id = ?
    `;
    const countResult = await queryDb(countMemberSql, [newGroupId]);
    const memberCount = countResult[0].memberCount || 1;

    const newGroup = {
      groupId: newGroupId,
      groupName: trimmedGroupName,
      groupLeaderId: leaderId,
      groupLeaderNickname: groupLeaderNickname,
      role: "creator",
      joinTime: new Date().toISOString(),
      description: description.trim(),
      memberCount: memberCount
    };

    //返回成功响应
    res.status(200).json({
      status: 200,
      message: "小组创建成功，已自动加入该小组",
      data: newGroup
    });

  } catch (err) {
    console.error("创建小组异常:", err.stack);
    res.status(500).json({
      status: 500,
      message: "创建小组失败：服务器内部错误",
      error: process.env.NODE_ENV === 'development' ? err.message : undefined
    });
  }
};
// 邀请伙伴加入小组
const inviteUserToGroup = async (req, res) => {
  try {
    // 解析请求参数（邀请者ID、小组ID、被邀请者ID）
    const { 
      inviterUserId,    // 邀请者ID（必须是组长）
      groupId,          // 目标小组ID
      targetUserId      // 被邀请者ID（要加入小组的用户）
    } = req.body;

    // 严格参数校验（非空+数字格式）
    const validateNum = (val, name) => {
      if (!val || isNaN(Number(val))) {
        return `参数错误：${name}不能为空且必须为有效数字`;
      }
      return "";
    };
    const inviterErr = validateNum(inviterUserId, "邀请者ID");
    const groupErr = validateNum(groupId, "小组ID");
    const targetErr = validateNum(targetUserId, "被邀请者ID");
    if (inviterErr || groupErr || targetErr) {
      return res.status(400).json({
        status: 400,
        message: inviterErr || groupErr || targetErr
      });
    }

    // 转换为数字类型（匹配数据库INT字段）
    const inviterId = Number(inviterUserId);
    const targetGroupId = Number(groupId);
    const targetId = Number(targetUserId);

    // 校验1：邀请者与被邀请者不能是同一人
    if (inviterId === targetId) {
      return res.status(400).json({
        status: 400,
        message: "邀请失败：不能邀请自己加入小组"
      });
    }

    //校验2：小组是否存在
    const checkGroupSql = `
      SELECT id, name AS groupName, leader_id AS groupLeaderId 
      FROM study_groups 
      WHERE id = ?
    `;
    const groupResult = await queryDb(checkGroupSql, [targetGroupId]);
    if (groupResult.length === 0) {
      return res.status(404).json({
        status: 404,
        message: "邀请失败：该小组不存在或已解散"
      });
    }
    const { groupName, groupLeaderId } = groupResult[0];

    // 校验3：邀请者是否为该小组组长（仅组长有邀请权限）
    if (inviterId !== groupLeaderId) {
      return res.status(403).json({
        status: 403,
        message: "无权限：仅小组组长可邀请成员加入"
      });
    }

    // 校验4：被邀请者是否为有效用户（存在于users表）
    const checkTargetUserSql = `
      SELECT id, nickname AS targetNickname, avatar AS targetAvatar 
      FROM users 
      WHERE id = ?
    `;
    const targetUserResult = await queryDb(checkTargetUserSql, [targetId]);
    if (targetUserResult.length === 0) {
      return res.status(404).json({
        status: 404,
        message: "邀请失败：被邀请的用户不存在"
      });
    }
    const { targetNickname, targetAvatar } = targetUserResult[0];

    // 校验5：被邀请者是否已加入该小组（避免重复邀请）
    const checkJoinedSql = `
      SELECT user_id 
      FROM group_members 
      WHERE user_id = ? AND group_id = ?
    `;
    const joinedResult = await queryDb(checkJoinedSql, [targetId, targetGroupId]);
    if (joinedResult.length > 0) {
      return res.status(409).json({ // 409 资源冲突
        status: 409,
        message: `邀请失败：${targetNickname}已加入小组【${groupName}】`
      });
    }

    // 核心操作：添加被邀请者到 group_members 表（自动加入小组）
    const insertMemberSql = `
      INSERT INTO group_members 
      (user_id, group_id, joined_at)
      VALUES (?, ?, CURRENT_TIMESTAMP)
    `;
    await queryDb(insertMemberSql, [targetId, targetGroupId]);

    //组装返回数据（包含小组、邀请者、被邀请者信息，便于前端展示）
    const inviterNicknameResult = await queryDb(`SELECT nickname FROM users WHERE id = ?`, [inviterId]);
    const inviterNickname = inviterNicknameResult[0]?.nickname || "未知组长";
    
    const resultData = {
      groupInfo: {
        groupId: targetGroupId,
        groupName: groupName
      },
      inviterInfo: {
        inviterUserId: inviterId,
        inviterNickname: inviterNickname
      },
      targetUserInfo: {
        targetUserId: targetId,
        targetNickname: targetNickname,
        targetAvatar: targetAvatar || "/default-avatar.png"
      },
      joinTime: new Date().toISOString(),
      role: "member" // 被邀请者默认是普通成员
    };

    // 返回成功响应
    res.status(200).json({
      status: 200,
      message: "邀请成功",
      data: resultData
    });

  } catch (err) {
    console.error("邀请成员加入小组异常:", err.stack);
    res.status(500).json({
      status: 500,
      message: "邀请失败：服务器内部错误",
      error: process.env.NODE_ENV === 'development' ? err.message : undefined
    });
  }
};
//获得小组成员
const getGroupMembers = async (req, res) => {
  try {
    //参数校验
    const { groupId } = req.query;
    if (!groupId || isNaN(Number(groupId))) {
      return res.status(400).json({
        status: 400,
        message: "参数错误：小组ID不能为空且必须为数字"
      });
    }
    const targetGroupId = Number(groupId);

    // 查询小组成员
    const queryMembersSql = `
      SELECT 
        user_id AS userId,          
        user_nickname AS nickname
      FROM user_group_relation
      WHERE group_id = ?            
      ORDER BY 
        (user_id = group_leader_id) DESC  
      LIMIT 200  
    `;

    const membersResult = await queryDb(queryMembersSql, [targetGroupId]);

    // 数据格式化（填充默认值，避免前端处理空值）
    const formattedMembers = membersResult.map(member => ({
      userId: member.userId,
      nickname: member.nickname || "未知成员",  // 昵称空值兜底
    }));

    // 处理无成员场景（返回空数组，友好提示）
    if (formattedMembers.length === 0) {
      return res.status(200).json({
        status: 200,
        message: "当前小组暂无成员",
        data: [],
        total: 0  // 明确成员总数为0
      });
    }

    // 返回成功响应
    res.status(200).json({
      status: 200,
      message: "小组成员获取成功",
      data: formattedMembers,
      total: formattedMembers.length  // 成员总数（前端无需自己计算）
    });

  } catch (err) {
    // 错误处理
    console.error("获取小组成员异常:", err.stack);  // 打印详细堆栈（便于排查）
    res.status(500).json({
      status: 500,
      message: "获取小组成员失败：服务器内部错误",
      // 开发环境返回具体错误信息，生产环境隐藏（避免暴露敏感信息）
      error: process.env.NODE_ENV === 'development' ? err.message : undefined
    });
  }
};
//退出小组
const quitGroup = async (req, res) => {
  try {
    // 参数校验（必须传入用户ID和小组ID，均为数字）
    const { userId, groupId } = req.body;
    if (!userId || isNaN(Number(userId)) || !groupId || isNaN(Number(groupId))) {
      return res.status(400).json({
        status: 400,
        message: "参数错误：用户ID和小组ID不能为空且必须为数字"
      });
    }
    const targetUserId = Number(userId);
    const targetGroupId = Number(groupId);

    // 查询用户在该小组中的角色（基于视图 user_group_relation）
    // 核心：判断用户是组长还是普通成员（组长不能直接退出）
    const queryUserRoleSql = `
      SELECT 
        group_leader_id AS groupLeaderId,
        -- 角色判断：组长（creator）/普通成员（member）
        CASE 
          WHEN ? = group_leader_id THEN 'creator' 
          ELSE 'member' 
        END AS role
      FROM user_group_relation
      WHERE user_id = ? AND group_id = ?
      LIMIT 1  -- 确保只返回一条关联记录
    `;
    const roleResult = await queryDb(queryUserRoleSql, [targetUserId, targetUserId, targetGroupId]);

    // 处理“用户未加入该小组”场景
    if (roleResult.length === 0) {
      return res.status(400).json({
        status: 400,
        message: "无法退出：你未加入该小组"
      });
    }

    const userRole = roleResult[0].role;
    // 禁止组长直接退出（需先转让组长或解散小组）
    if (userRole === 'creator') {
      return res.status(403).json({
        status: 403,
        message: "无法退出：你是小组组长，请先转让组长权限或解散小组"
      });
    }

    // 5. 执行退出操作：删除 group_members 表中的关联记录
    const quitGroupSql = `
      DELETE FROM group_members
      WHERE user_id = ? AND group_id = ?
    `;
    const deleteResult = await queryDb(quitGroupSql, [targetUserId, targetGroupId]);

    //验证删除结果（理论上不会走到，因前面已校验用户在组）
    if (deleteResult.affectedRows === 0) {
      return res.status(500).json({
        status: 500,
        message: "退出失败：未找到对应的小组成员关联记录"
      });
    }

    // 可选：补充查询退出后小组的剩余成员数（提升接口信息完整性）
    const queryRemainingMembersSql = `
      SELECT COUNT(DISTINCT user_id) AS remainingMemberCount
      FROM user_group_relation
      WHERE group_id = ?
    `;
    const memberCountResult = await queryDb(queryRemainingMembersSql, [targetGroupId]);
    const remainingMemberCount = memberCountResult[0].remainingMemberCount || 0;

    // 返回成功响应
    res.status(200).json({
      status: 200,
      message: "退出小组成功",
      data: {
        groupId: targetGroupId,
        userId: targetUserId,
        remainingMemberCount: remainingMemberCount  // 退出后小组剩余人数
      }
    });

  } catch (err) {
    // 错误处理
    console.error("退出小组异常:", err.stack);
    res.status(500).json({
      status: 500,
      message: "退出小组失败：服务器内部错误",
      error: process.env.NODE_ENV === 'development' ? err.message : undefined
    });
  }
};
module.exports={
  getUserGroups,
  getGroupPosts,
  sendGroupPost,
  groupChatWithdraw,
  createStudyGroup,
  inviteUserToGroup,
  getGroupMembers,  
  quitGroup
}